#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/sem.h>

struct sembuf up = {0, 1, 0};

struct sembuf down = {0, -1, 0};

int semaphore_create()
{
  int semaphore_id = semget(IPC_PRIVATE, 1, 0600);
  if (semaphore_id < 0) {
    printf("Error creating semaphore");
    exit(1);
  }
  return semaphore_id;
}

void semaphore_down(int semaphore_id)
{
  if (semop(semaphore_id, &down, 1) < 0) {
    printf("Error locking semaphore");
    exit(1);
  }
}

void semaphore_up(int semaphore_id)
{
  if (  semop(semaphore_id, &up, 1) < 0) {
    printf("Error locking semaphore");
    exit(1);
  }
}

void semaphore_destroy(int semaphore_id) 
{
  if (semctl(semaphore_id, 0, IPC_RMID) < 0) {
    printf("Error locking semaphore");
    exit(1);
  }
}


void display(char *str) 
{
  char *tmp;
  for (tmp=str;*tmp;tmp++) {
    write(1,tmp,1);
    usleep(100);
  }
}

int main() 
{
  int i;
  int semaphore_ab = semaphore_create();
  int semaphore_cd = semget(IPC_PRIVATE, 1, 0600);
  if (semaphore_cd < 0) {
    printf("Error creating semaphore");
    semaphore_destroy(semaphore_ab);    
    exit(1);
  }
  semaphore_up(semaphore_ab);

  if (fork()) {
    for (i=0;i<10;i++) {
      semaphore_down(semaphore_ab);
      display("ab");
      semaphore_up(semaphore_cd);
    }
    wait(NULL);
    semaphore_destroy(semaphore_ab);    
    semaphore_destroy(semaphore_cd);
  }
  else {
    for (i=0;i<10;i++) {
      semaphore_down(semaphore_cd);
      display("cd\n");
      semaphore_up(semaphore_ab);
   }
  }
  return 0;
}



